#!/bin/bash
# 功能：配置postgres主从，具有自动故障切换功能
# 前提：需要配置免密,当前主机到node1 node1 ssh免密即可

source comm.cfg

color_text() {
    local color=$1
    local text=$2
    echo -e "\e[${color}m${text}\e[0m"
}

error() {
    color_text "31" "$1"
}

info() {
    color_text "32" "$1"
}
# 安装主库
function installprimary() {
sudo apt update
sudo apt install postgresql-14 -y
sudo apt-get install postgresql-14-repmgr -y
sed -i '/cluster_name/s/14\/main/node1/' /etc/postgresql/14/main/postgresql.conf
cat <<EOF >> /etc/postgresql/14/main/postgresql.conf
listen_addresses = '*'
max_wal_senders = 10
max_replication_slots = 10
wal_level = 'hot_standby'
hot_standby = on
archive_mode = on   # repmgr 本身不需要 WAL 文件归档。
archive_command = '/bin/true'
shared_preload_libraries = 'repmgr'
wal_log_hints = 'on'
EOF
# 创建repmgr需要的用户
su -l postgres -c "createuser -s repmgr"
su -l postgres -c "createdb repmgr -O repmgr"

sed -i '/# DO NOT DISABLE!/i \
local   replication   repmgr                              trust \
host    replication   repmgr      127.0.0.1/32            trust \
host    replication   repmgr      0.0.0.0/0               trust \
local   repmgr        repmgr                              trust \
host    repmgr        repmgr      127.0.0.1/32            trust \
host    repmgr        repmgr      0.0.0.0/0               trust \
host    maasclidb     maascli     0.0.0.0/0               md5' /etc/postgresql/14/main/pg_hba.conf

cat <<EOF > /etc/postgresql/14/main/repmgr.conf
node_id=1
node_name='${PRIMARY}'
conninfo='host=${PRIMARY} user=repmgr dbname=repmgr connect_timeout=2'
data_directory='/var/lib/postgresql/14/main'
# 日志管理
log_level='INFO'
log_file='/tmp/repmgr.log'
# failover设置
failover='automatic'
promote_command='/usr/bin/repmgr standby promote -f /etc/postgresql/14/main/repmgr.conf --log-to-file'
follow_command='/usr/bin/repmgr standby follow -f /etc/postgresql/14/main/repmgr.conf --log-to-file --upstream-node-id=%n'
# 用于repmgr启停pg
service_start_command   = 'sudo pg_ctlcluster 14 main start'
service_stop_command    = 'sudo pg_ctlcluster 14 main stop'
service_restart_command = 'sudo pg_ctlcluster 14 main restart'
service_reload_command  = 'sudo pg_ctlcluster 14 main reload'
EOF

echo "postgres        ALL=(ALL)       NOPASSWD: ALL" > /etc/sudoers.d/postgres

sudo systemctl restart postgresql@14-main.service
if [ $? -eq 0 ];then
    info "postgresql配置完成"
fi
su -l postgres -c "repmgr -f /etc/postgresql/14/main/repmgr.conf primary register"
if [ $? -eq 0 ];then
    info "primary register完成"
fi
su -l postgres -c "repmgr -f /etc/postgresql/14/main/repmgr.conf cluster show"

cat <<EOF > /etc/default/repmgrd
REPMGRD_ENABLED=yes
REPMGRD_CONF="/etc/postgresql/14/main/repmgr.conf"
REPMGRD_OPTS="--daemonize=false"
EOF
systemctl restart repmgrd
if [ $? -eq 0 ];then
    info "repmgrd 配置完成"
fi
info "primary安装完成"
su - postgres -c 'repmgr -f /etc/postgresql/14/main/repmgr.conf service status'
}
# 安装从库
function installstandby() {
sudo apt update
sudo apt install postgresql-14 -y
sudo apt-get install postgresql-14-repmgr -y
sed -i '/cluster_name/s/14\/main/node2/' /etc/postgresql/14/main/postgresql.conf
cat <<EOF >> /etc/postgresql/14/main/postgresql.conf
listen_addresses = '*'
max_wal_senders = 10
max_replication_slots = 10
wal_level = 'hot_standby'
hot_standby = on
archive_mode = on   # repmgr 本身不需要 WAL 文件归档。
archive_command = '/bin/true'
shared_preload_libraries = 'repmgr'
wal_log_hints = 'on'
EOF

cat <<EOF > /etc/postgresql/14/main/repmgr.conf
node_id=2
node_name='${STANDBY}'
conninfo='host=${STANDBY} user=repmgr dbname=repmgr connect_timeout=2'
data_directory='/var/lib/postgresql/14/main'
# 日志管理
log_level='INFO'
log_file='/tmp/repmgr.log'
# failover设置
failover='automatic'
promote_command='/usr/bin/repmgr standby promote -f /etc/postgresql/14/main/repmgr.conf --log-to-file'
follow_command='/usr/bin/repmgr standby follow -f /etc/postgresql/14/main/repmgr.conf --log-to-file --upstream-node-id=%n'
# 用于repmgr启停pg
service_start_command   = 'sudo pg_ctlcluster 14 main start'
service_stop_command    = 'sudo pg_ctlcluster 14 main stop'
service_restart_command = 'sudo pg_ctlcluster 14 main restart'
service_reload_command  = 'sudo pg_ctlcluster 14 main reload'
EOF
echo "postgres        ALL=(ALL)       NOPASSWD: ALL" > /etc/sudoers.d/postgres
# 添加repmgr无密码登录pg
sed -i '/# DO NOT DISABLE!/i \
local   replication   repmgr                              trust \
host    replication   repmgr      127.0.0.1/32            trust \
host    replication   repmgr      0.0.0.0/0               trust \
local   repmgr        repmgr                              trust \
host    repmgr        repmgr      0.0.0.0/0               trust \
host    maasclidb     maascli     0.0.0.0/0               md5' /etc/postgresql/14/main/pg_hba.conf

systemctl stop postgresql@14-main.service
rm -rf /var/lib/postgresql/14/main/*

dbready ${PRIMARY}
su -l postgres -c "repmgr -h ${PRIMARY} -U repmgr -d repmgr -f /etc/postgresql/14/main/repmgr.conf standby clone --dry-run"
if [ $? -ne 0 ];then
    error "standby clone error"
    exit 1
fi
su -l postgres -c "repmgr -h ${PRIMARY} -U repmgr -d repmgr -f /etc/postgresql/14/main/repmgr.conf standby clone"
if [ $? -eq 0 ];then
    info "standby clone完成"
fi
systemctl start postgresql@14-main.service
if [ $? -eq 0 ];then
    info "pg启动完成"
fi
su -l postgres -c "repmgr -f /etc/postgresql/14/main/repmgr.conf standby register"
if [ $? -eq 0 ];then
    info "standby register完成"
fi
su -l postgres -c "repmgr -f /etc/postgresql/14/main/repmgr.conf cluster show"

cat <<EOF > /etc/default/repmgrd
REPMGRD_ENABLED=yes
REPMGRD_CONF="/etc/postgresql/14/main/repmgr.conf"
REPMGRD_OPTS="--daemonize=false"
EOF

systemctl restart repmgrd
if [ $? -eq 0 ];then
    info "repmgrd配置完成"
fi
su - postgres -c 'repmgr -f /etc/postgresql/14/main/repmgr.conf service status'
info "standby安装成功"
}
# 探测pg是否就绪
dbready() {
    for i in $(seq 1 10)
    do
        nc -zv $1 5432 &> /dev/null
        if [ $? -ne 0 ];then
            error "Waiting Ready......"
            sleep 10
        else
            info "$1 PG Is Ready"
            return 0
        fi
    done
    error "Waiting PG Timeout"
    return 1
}

pginstall() {
    ip a |grep ${PRIMARY}
    if [ $? -eq 0 ];then
        installprimary
    else
        installstandby
    fi
}

pginstall